package fun.codedesign.jdk.math.iterator;

import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class Iterators {
    /**
     * 将多个迭代器作为返回一个迭代器来使用
     * <p> 采用一个静态内部类来重写迭代器方法，并且接收一个迭代器list来进行处理
     */
    public static void main(String[] args) {
        Iterator<Integer> a = Arrays.asList(1, 2, 3, 4, 5).iterator();
        Iterator<Integer> b = Arrays.asList(6).iterator();
        Iterator<Integer> c = Collections.emptyIterator();
        Iterator<Integer> d = Collections.emptyIterator();
        Iterator<Integer> e = Arrays.asList(7, 8, 9).iterator();

        Iterator<Integer> singleIterator = singleIterator(Arrays.asList(a, b, c, d, e));
        while (singleIterator.hasNext()) {
            System.out.println(singleIterator.next());
        }
    }


    /**
     * 返回一个折叠的迭代器，可以判断是否有下一个迭代器存在
     *
     * @param iterators
     * @return
     */
    public static <E> ListIterator<E> singleIterator(List<Iterator<E>> iterators) {
        return new ListIterator<E>(iterators);
    }


    public static class ListIterator<E> implements Iterator<E> {

        /**
         * 当前迭代器
         */
        private Iterator<E> currentIterator;
        /**
         * 传入的迭代器集合
         */
        private Iterator<Iterator<E>> listIterator;

        /**
         * 初始构造
         *
         * @param currentIterator
         * @param iterators
         */
        public ListIterator(List<Iterator<E>> iterators) {
            this.listIterator = iterators.iterator();
            this.currentIterator = listIterator.next();
        }

        @Override
        public boolean hasNext() {
            if (!currentIterator.hasNext()) {
                // 当前迭代器没有下一个元素并且没有下一个迭代器接替返回false
                if (!listIterator.hasNext()) {
                    return false;
                }
                // 将下一个迭代器设置为当前迭代器，再次递归判断
                currentIterator = listIterator.next();
                hasNext();
            }
            return true;
        }

        @Override
        public E next() {
            //hasNext();
            return currentIterator.next();
        }

        @Override
        public void remove() {
            hasNext();
            currentIterator.remove();
        }
    }
}
